var instance = null;
var i = 1; // 随机数，生成节点时累加，避免缓存在造成的节点Point错乱
var x = 0;
var eqNodeArray = []; // 数组，用来保存已经存在的节点
$(function () {
  jsPlumb.ready(function () {
    instance = jsPlumb.getInstance({
      DragOptions: {cursor: "pointer", zIndex: 2000},
      ConnectionOverlays: [
        [ "Arrow", {
          location: 1,
          visible:true,
          width:11,
          length:11,
          id:"ARROW"
        }]
      ],
      Container: "flow-panel"
    });

    $('#left-wrapper .node').attr('draggable', 'true').on('dragstart', function (ev) {
      ev.originalEvent.dataTransfer.setData('text', ev.target.textContent+","+ev.target.id);
    });

    $('#flow-panel').on('drop', function (ev) {
      if (ev.target.className.indexOf('_jsPlumb') >= 0) {
        return;
      }
      ev.preventDefault();
      var data = ev.originalEvent.dataTransfer.getData('text');
      //var id = 'node'+data.split(",")[1];
      var id = 'node'+data.split(",")[1] + '-' + (i++).toString() + '-';
      for (var z = 0; z < eqNodeArray.length; z++) {
        if (eqNodeArray[z] == 'node'+data.split(",")[1]) {
          $.modal.msgError("已存在此流程节点，请重新选择");
          return;
        }
      }
      eqNodeArray[x++] = 'node'+data.split(",")[1];
      // if ($("#"+equId).length > 0) {
      //   $.modal.msgError("已存在此流程节点，请重新选择");
      //   return;
      // }
      var text = data.split(",")[0];
      var mx = '' + (ev.originalEvent.offsetX - 60) + 'px';
      var my = '' + (ev.originalEvent.offsetY - 25) + 'px';
      addNode(instance, id, text, {x: mx, y: my});
    }).on('dragover', function (ev) {
      ev.preventDefault();
    });

    $('#flow-panel').on("click", ".button-remove", function () {
      const parentnode = $(this)[0].parentNode.parentNode;
      eqNodeArray.remove(parentnode.id.toString().substring(0, parentnode.id.toString().indexOf('-')));
      instance.deleteConnectionsForElement(parentnode);
      instance.removeAllEndpoints(parentnode);
      $(parentnode).remove();
    });

    instance.batch(function () {
      var flowdata = $("#jsonOutput").val();
      if(flowdata) {
        loadFlowchart(flowdata);
      }
    });
    jsPlumb.fire("jsFlowLoaded", instance);
  });

});

var connectorPaintStyle = {
    strokeWidth: 2,
    stroke: "#61B7CF",
    joinstyle: "round",
    outlineStroke: "white",
    outlineWidth: 2
  },
  connectorHoverStyle = {
    strokeWidth: 3,
    stroke: "#216477",
    outlineWidth: 5,
    outlineStroke: "white"
  },
  endpointHoverStyle = {
    fill: "#216477",
    stroke: "#216477"
  },
  // the definition of source endpoints (the small blue ones)
  sourceEndpoint = {
    endpoint: "Dot",
    paintStyle: {
      stroke: "#7AB02C",
      fill: "transparent",
      radius: 7,
      strokeWidth: 1
    },
    isSource: true,
    connector: [ "Flowchart", { stub:[20,40], gap:0, cornerRadius:5, alwaysRespectStubs:true } ],
    connectorStyle: connectorPaintStyle,
    hoverPaintStyle: endpointHoverStyle,
    connectorHoverStyle: connectorHoverStyle,
    maxConnections: -1,
    dragOptions: {},
    overlays: [
      [ "Label", {
        location: [0.5, 1.5],
        label: "Drag",
        cssClass: "endpointSourceLabel",
        visible:false
      } ]
    ]
  },
  targetEndpoint = {
    endpoint: "Dot",
    paintStyle: { fill: "#7AB02C", radius: 7 },
    hoverPaintStyle: endpointHoverStyle,
    maxConnections: -1,
    dropOptions: { hoverClass: "hover", activeClass: "active" },
    isTarget: true,
    overlays: [
      [ "Label", { location: [0.5, -0.5], label: "Drop", cssClass: "endpointTargetLabel", visible:false } ]
    ]
  };

function addNode(instance, nodeId, nodeLable, position) {
  var taskNode = `
        <div class="node window jtk-node po_r" id="${nodeId}" style="border: 1px #216477 solid; width: 120px; height: 50px; left: ${position.x}; top: ${position.y};">
          <div class="po_a">
            <div class="button-remove">x</div>
          </div>
          <div style="width: 100%; height: 100%;line-height: 36px;text-align: center;">${nodeLable}</div>
        </div>
      `;
  $(taskNode).appendTo("#flow-panel");
  let node = jsPlumb.getSelector('#' + nodeId)[0];
  if (nodeId.indexOf('raw') >= 0) {
    addEndpoint(instance, node, ["BottomCenter"], []);
  } else {
    addEndpoint(instance, node, ["BottomCenter"], ["TopCenter","LeftMiddle", "RightMiddle"]);
  }
  instance.draggable($(node));
}

function addEndpoint(instance, node, sourceAnchors, targetAnchors) {
  var nid = node.getAttribute("id");
  for (var i = 0; i < sourceAnchors.length; i++) {
    var sourceUUID = nid + sourceAnchors[i];
    instance.addEndpoint(node, sourceEndpoint, {
      anchor: sourceAnchors[i], uuid: sourceUUID
    });
  }
  for (var j = 0; j < targetAnchors.length; j++) {
    var targetUUID = nid + targetAnchors[j];
    instance.addEndpoint(node, targetEndpoint, { anchor: targetAnchors[j], uuid: targetUUID });
  }
}

function saveFlowchart() {
  var nodes = [];
  var flowIds = [];
  $("#flow-panel .node").each(function(idx, elem) {
    var $elem = $(elem);
    //var _id = $elem.attr("id");
    var _id;
    if ($elem.attr("id").indexOf('-') == -1)
      _id = $elem.attr("id");
    else
      _id = $elem.attr("id").substring(0, $elem.attr("id").lastIndexOf('-'));
    nodes.push({
      nodeId: _id,
      nodeText: $.trim($elem.children().next().html()),
      positionX: parseInt($elem.css("left"), 10),
      positionY: parseInt($elem.css("top"), 10)
    });
    if(_id.indexOf('raw') == -1) {
      flowIds.push(_id.substring(4));
    }
  });
  var connections = [];
  $.each(instance.getConnections(), function(idx, connection) {
    connections.push({
      uuids: connection.getUuids()
    });
  });
  var flowChart = {};
  flowChart.nodes = nodes;
  flowChart.connections = connections;
  $("#flowIds").val(flowIds.join());
  return JSON.stringify(flowChart);
  // var flowChartJson = JSON.stringify(flowChart);
  // $("#jsonOutput").val(flowChartJson);
}

function loadFlowchart(flowdata) {
  // var flowChartJson = $("#jsonOutput").val();
  var flowChart = JSON.parse(flowdata);
  console.info('load data:' + flowdata);
  var nodes = flowChart.nodes;

  $.each(nodes, function(index, elem) {
    //var id = elem.nodeId;
    var id;
    if (elem.nodeId.indexOf('-') == -1)
      id = elem.nodeId;
    else
      id = elem.nodeId.substring(0, elem.nodeId.indexOf('-'));
    console.info('load node id:' + id);
    var text = elem.nodeText;
    var posX = elem.positionX;
    var posY = elem.positionY;
    eqNodeArray[x++] = id;
    addNode(instance, id, text, {x: posX, y: posY});
    repositionElement(id, posX, posY);
  });
  var connections = flowChart.connections;
  $.each(connections, function (index, elem) {
    var strUuids = elem.uuids.toString();
    var firstPoint = strUuids.split(',')[0];
    var startPoint = firstPoint.substring(0, firstPoint.indexOf('-'));
    startPoint += firstPoint.substring(firstPoint.lastIndexOf('-') + 1, firstPoint.length);
    var secondPoint = strUuids.split(',')[1];
    var endPoint = secondPoint.substring(0, secondPoint.indexOf('-'));
    endPoint += secondPoint.substring(secondPoint.lastIndexOf('-') + 1, secondPoint.length);
    var pointsArray = [startPoint, endPoint];
    var data = {
      uuids : pointsArray
    };
    instance.connect({
      uuids: data.uuids
    });

    // instance.connect({
    //   uuids: elem.uuids
    // });
  });
  instance.repaintEverything();
}

function repositionElement(id, posX, posY) {
  $('#'+id).css("left", posX);
  $('#'+id).css("top", posY);
  instance.repaint(id);
}

function flowImage() {
  scrollTo(0, 0);
  // var nodesToRecover = [];
  // var nodesToRemove = [];
  var svgElem = $("#flow-panel").find('svg');
  svgElem.each(function (index, node) {
    var parentNode = node.parentNode;
    var svg = node.outerHTML.trim();
    var canvas = document.createElement('canvas');
    canvg(canvas, svg);
    if (node.style.position) {
      canvas.style.position = node.style.position;
      canvas.style.left = node.style.left;
      canvas.style.top = node.style.top;
    }
    /*nodesToRecover.push({
      parent: parentNode,
      child: node
    });*/
    parentNode.removeChild(node);
    // nodesToRemove.push({
    //   parent: parentNode,
    //   child: canvas
    // });
    parentNode.appendChild(canvas);
  });
  var flowpanel = document.getElementById('flow-panel');
  var width = flowpanel.offsetWidth;
  var height = flowpanel.offsetHeight;
  var canvas = document.createElement("canvas");
  canvas.width = width;
  canvas.height = height;
  canvas.style.width = width + 'px';
  canvas.style.height = height + 'px';
  var opts = {
    canvas:canvas,
    width:width,
    height:height,
    backgroundColor: 'transparent',
  };
  return html2canvas(flowpanel,opts).then(function (canvas) {
    var urldata = canvas.toDataURL();
    // $('<img>',{src:urldata}).appendTo($('body'));
    urldata = urldata.substring(urldata.indexOf(",") + 1);
    return urldata;
  });
}
Array.prototype.indexOf = function(val) {
  for (var i = 0; i < this.length; i++) {
    if (this[i] == val) return i;
  }
  return -1;
};
Array.prototype.remove = function(val) {
  var index = this.indexOf(val);
  if (index > -1) {
    this.splice(index, 1);
  }
};